package com.fa4j.system.account.service.impl;

import com.fa4j.common.base.exception.CommonRequestError;
import com.fa4j.common.base.model.RemoveCmd;
import com.fa4j.common.base.util.ValidUtil;
import com.fa4j.system.account.convert.AccountConverter;
import com.fa4j.system.account.model.Account;
import com.fa4j.system.account.model.AccountCreateCmd;
import com.fa4j.system.account.model.AccountEvent;
import com.fa4j.system.account.model.AccountModifyCmd;
import com.fa4j.system.account.repository.AccountRepository;
import com.fa4j.system.account.service.AccountService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.Objects;

/**
 * 系统账号 服务接口实现
 *
 * @since 2025-05-06 16:16:26
 */
@Slf4j
@Service
@Validated
@RequiredArgsConstructor
public class AccountServiceImpl implements AccountService {

    private final AccountRepository accountRepository;
    private final AccountConverter accountConverter;

    private final ApplicationEventPublisher publisher;


    /**
     * 创建账号信息
     *
     * @param cmd 参数
     * @return 编辑后的账号信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Account create(@Valid AccountCreateCmd cmd) {
        ValidUtil.validInUsed("用户名", () -> accountRepository.findByUsername(cmd.getAppType(), cmd.getUsername()));
        ValidUtil.validInUsed("手机号码", () -> accountRepository.findByPhone(cmd.getAppType(), cmd.getPhone()));
        ValidUtil.validInUsed("电子邮箱", () -> accountRepository.findByEmail(cmd.getAppType(), cmd.getEmail()));
        Account account = accountConverter.toEntity(cmd);
        accountRepository.create(account);
        publisher.publishEvent(new AccountEvent.Create(account));
        return account;
    }

    /**
     * 编辑账号信息
     *
     * @param cmd 参数
     * @return 编辑后的账号信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Account modify(@Valid AccountModifyCmd cmd) {
        Account account = accountRepository.findById(cmd.getId())
                .orElseThrow(() -> CommonRequestError.NOT_FOUND.build("账号"));
        Account beforeData = accountConverter.clone(account);
        if (!Objects.equals(account.getPhone(), cmd.getPhone())) {
            // 号码修改手机,校验手机号码是否被占用
            ValidUtil.validInUsed("手机号码", () -> accountRepository.findByPhone(account.getAppType(), cmd.getPhone()));
        }
        if (!Objects.equals(account.getEmail(), cmd.getEmail())) {
            // 邮箱地址修改,校验邮箱地址是否被占用
            ValidUtil.validInUsed("电子邮箱", () -> accountRepository.findByEmail(account.getAppType(), cmd.getEmail()));
        }
        accountConverter.updateEntity(account, cmd);
        accountRepository.modify(account);
        publisher.publishEvent(new AccountEvent.Modify(beforeData, account));
        return account;
    }


    /**
     * 删除账号信息
     *
     * @param cmd 删除信息
     * @return 删除的账号信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Account remove(@Valid RemoveCmd<Long> cmd) {
        Account account = accountRepository.findById(cmd.getId())
                .orElseThrow(CommonRequestError.NOT_FOUND::build);
        account.setOperatorId(cmd.getOperatorId());
        accountRepository.remove(account);
        publisher.publishEvent(new AccountEvent.Remove(account));
        return account;
    }
}




